package com.atguigu.tingshu.search.listener;


import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.album.client.CategoryFeignClient;
import com.atguigu.tingshu.common.constant.RabbitConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.BaseCategoryView;
import com.atguigu.tingshu.model.search.AlbumInfoIndex;
import com.atguigu.tingshu.model.search.AttributeValueIndex;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

@Component
public class AlbumListener {
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Autowired
    private CategoryFeignClient categoryFeignClient;

    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(RabbitConstant.ALBUM_SAVE_QUEUE),
            exchange=@Exchange(value =RabbitConstant.ALBUM_EXCHANGE,
                    type = ExchangeTypes.TOPIC,ignoreDeclarationExceptions = "true"),
            key = RabbitConstant.ALBUM_SAVE_RK
    ))
    public void saveAlbum(Long albumId, Channel channel, Message message) throws IOException {
        if (albumId == null){
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            return;
        }


        try {
            //根据专辑id查询专辑
            Result<AlbumInfo> albumInfoResult = this.albumInfoFeignClient.getAlbumInfo(albumId);
            Assert.notNull(albumInfoResult,"专辑数据实时同步时,获取专辑数据失败!"+albumId);
            AlbumInfo albumInfo = albumInfoResult.getData();
            Assert.notNull(albumInfo,"专辑数据实时同步时,对应的专辑不存在!"+albumId);

            AlbumInfoIndex index = new AlbumInfoIndex();
            BeanUtils.copyProperties(albumInfo, index);

            //根据主播id查询主播
            Result<UserInfo> userInfoResult = this.userInfoFeignClient.queryUserById(albumInfo.getUserId());
            Assert.notNull(userInfoResult,"数据导入时,获取主播信息失败!"+albumInfo.getUserId());
            UserInfo userInfo = userInfoResult.getData();
            if (userInfo != null) {
                index.setAnnouncerName(userInfo.getNickname());
            }
            //根据三级分类的id查询三级分类
            Result<BaseCategoryView> baseCategoryViewResult = this.categoryFeignClient.queryCategoryView(albumInfo.getCategory3Id());
            Assert.notNull(baseCategoryViewResult,"数据导入时,获取三级分类失败! "+albumInfo.getCategory3Id());
            BaseCategoryView baseCategoryView = baseCategoryViewResult.getData();
            if (baseCategoryView!=null){
                index.setCategory1Id(baseCategoryView.getCategory1Id());
                index.setCategory2Id(baseCategoryView.getCategory2Id());
            }

            //热度,根据统计信息动态计算
            index.setPlayStatNum(new Random().nextInt(10) * 1000000);
            index.setSubscribeStatNum(new Random().nextInt(10) * 1000000);
            index.setBuyStatNum(new Random().nextInt(10) * 1000000);
            index.setCommentStatNum(new Random().nextInt(10) * 1000000);
            index.setHotScore(index.getPlayStatNum() * 0.1 + index.getSubscribeStatNum() * 0.3
                    + index.getBuyStatNum() * 0.4 + index.getCommentStatNum() * 0.2);
            //根据专辑id查询专辑的标签信息
            Result<List<AlbumAttributeValue>> attributeValuesResult = this.albumInfoFeignClient.queryAttributeValues(albumId);
            Assert.notNull(attributeValuesResult,"数据导入时,获取标签信息失败!"+albumId);
            List<AlbumAttributeValue> attributeValues = attributeValuesResult.getData();
            if (!CollectionUtils.isEmpty(attributeValues)){
                //把AlbumAttributeValue转化成AttributeValueIndex对象集合
                index.setAttributeValueIndexList(attributeValues.stream().map(albumAttributeValue -> {
                    AttributeValueIndex attributeValueIndex = new AttributeValueIndex();
                    BeanUtils.copyProperties(albumAttributeValue,attributeValueIndex);
                    return attributeValueIndex;
                }).collect(Collectors.toList()));
            }
            this.elasticsearchTemplate.save(index);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            if (message.getMessageProperties().getRedelivered()){
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }else {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }
            throw new RuntimeException(e);
        }
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(RabbitConstant.ALBUM_DELETE_QUEUE),
            exchange=@Exchange(value = RabbitConstant.ALBUM_EXCHANGE,type=ExchangeTypes.TOPIC,ignoreDeclarationExceptions = "true"),
            key = RabbitConstant.ALBUM_DELETE_RK
    ))
    public void deleteAlbum(Long albumId,Channel channel,Message message) throws IOException {
        if (albumId==null){
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            return;
        }
        try {
            this.elasticsearchTemplate.delete(albumId.toString(),AlbumInfoIndex.class);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        }catch (Exception e){
            if (message.getMessageProperties().getRedelivered()){
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }else {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }
            throw new RuntimeException(e);
        }

    }
}
